package com.msf.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.msf.common.constant.CacheConstant;
import com.msf.common.constant.CommonConstant;
import com.msf.common.domain.dto.LoginModel;
import com.msf.common.domain.query.PageQuery;
import com.msf.common.domain.vo.Result;
import com.msf.common.utils.PasswordUtil;
import com.msf.common.utils.oConvertUtils;
import com.msf.common.constant.BizConstant;
import com.msf.modules.sys.domain.dto.RoleUserDto;
import com.msf.modules.sys.domain.dto.SysUserRoleDto;
import com.msf.modules.sys.domain.dto.UserDto;
import com.msf.modules.sys.domain.dto.UserEditDto;
import com.msf.modules.sys.entity.SysRole;
import com.msf.modules.sys.entity.SysUser;
import com.msf.modules.sys.entity.SysUserRole;
import com.msf.modules.sys.mapper.SysUserMapper;
import com.msf.modules.sys.service.ISysRoleService;
import com.msf.modules.sys.service.ISysUserRoleService;
import com.msf.modules.sys.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xujf
 * @since 2024-07-24
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Resource
    private ISysRoleService sysRoleService;

    @Override
    public Result<IPage<SysUser>> queryPageList(PageQuery pageQuery) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(
                SysUser::getId,
                SysUser::getUsername,
                SysUser::getRealname,
                SysUser::getPhone,
                SysUser::getStatus,
                SysUser::getOrgCode,
                SysUser::getOrgCodeTxt,
                SysUser::getDelFlag,
                SysUser::getCreateBy,
                SysUser::getCreateTime,
                SysUser::getUpdateBy,
                SysUser::getUpdateTime
        );
        String keywords = pageQuery.getKeywords();
        if (StringUtils.isNotEmpty(keywords)) {
            queryWrapper.and(wrapper -> {
                wrapper.like(SysUser::getUsername, keywords)
                        .or()
                        .like(SysUser::getRealname, keywords)
                        .or()
                        .like(SysUser::getPhone, keywords);
            });
        }
        //TODO 外部模拟登陆临时账号，列表不显示
        queryWrapper.ne(SysUser::getUsername, "_reserve_user_external");
        Page<SysUser> page = new Page<>(pageQuery.getPageNo(), pageQuery.getPageSize());
        IPage<SysUser> pageList = this.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    @Override
    public Result<?> add(UserDto userDto) {
        if (userDto == null) {
            return Result.error("参数必填");
        }
        if (StringUtils.isEmpty(userDto.getUsername()) || StringUtils.isEmpty(userDto.getRealname())) {
            return Result.error("参数必填");
        }
        SysUser sysUser = BeanUtil.toBean(userDto, SysUser.class);
        sysUser.setStatus(CommonConstant.STATUS_NORMAL);
        sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
        if (StringUtils.isEmpty(sysUser.getPassword())) {
            sysUser.setPassword(BizConstant.USER_DEFAULT_PASSWORD);
        }
        processPassword(sysUser);
        if (save(sysUser)) {
            sysUser.setPassword("");
            sysUser.setSalt("");
            return Result.OK("操作成功！", sysUser);
        } else {
            return Result.error("操作失败！");
        }
    }

    @Override
    public Result<?> edit(UserEditDto userDto) {
        if (userDto == null || StringUtils.isEmpty(userDto.getId())) {
            return Result.error("参数必填！");
        }
        SysUser sysUser = this.getById(userDto.getId());
        if (sysUser == null) {
            return Result.error("用户不存在，请刷新重试！");
        }
        sysUser.setRealname(userDto.getRealname());
        sysUser.setStatus(userDto.getStatus());
        sysUser.setOrgCode(userDto.getOrgCode());
        sysUser.setPhone(userDto.getPhone());
        if (updateById(sysUser)) {
            return Result.OK("更新成功！");
        } else {
            return Result.error("更新失败！");
        }
    }

    @Override
    @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(String id) {
        SysUser sysUser = this.getById(id);
        if (sysUser == null) {
            return;
        }
        if (!StringUtils.equals("admin", sysUser.getUsername())) {
            this.removeById(id);
            this.sysUserRoleService.removeByIds(
                    sysUserRoleService.lambdaQuery()
                            .eq(SysUserRole::getUserId, id)
                            .list()
                            .stream()
                            .map(SysUserRole::getId)
                            .collect(Collectors.toList())
            );
        }
    }

    @Override
    @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatchUsers(String ids) {
        if (ids != null && !ids.isEmpty()) {
            this.removeByIds(Arrays.asList(ids.split(",")));
            this.sysUserRoleService.removeByIds(
                    sysUserRoleService.lambdaQuery()
                            .in(SysUserRole::getUserId, Arrays.asList(ids.split(",")))
                            .list()
                            .stream()
                            .map(SysUserRole::getId)
                            .collect(Collectors.toList())
            );
        }
    }

    @Override
    public LoginModel getUserByName(String username) {
        return BeanUtil.toBean(lambdaQuery().eq(SysUser::getUsername, username).one(), LoginModel.class);
    }

    @Override
    public Result<List<String>> queryUserRole(String userId) {
        Result<List<String>> result = new Result<>();
        try {
            List<SysUserRole> list = sysUserRoleService.list(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getRoleId, userId));
            result.setResult(list.stream().map(e -> String.valueOf(e.getRoleId())).collect(Collectors.toList()));
            result.success("查询成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    @Override
    public Result<?> queryRoleUser(RoleUserDto roleUserDto) {
        if (StringUtils.isEmpty(roleUserDto.getRoleId())) {
            Result.error("参数不完整");
        }
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(
                SysUser::getId,
                SysUser::getUsername,
                SysUser::getRealname,
                SysUser::getPhone,
                SysUser::getStatus,
                SysUser::getOrgCode,
                SysUser::getOrgCodeTxt,
                SysUser::getDelFlag,
                SysUser::getCreateBy,
                SysUser::getCreateTime,
                SysUser::getUpdateBy,
                SysUser::getUpdateTime
        );
        List<String> userIds = sysUserRoleService.lambdaQuery()
                .eq(SysUserRole::getRoleId, roleUserDto.getRoleId())
                .list()
                .stream()
                .map(SysUserRole::getUserId)
                .collect(Collectors.toList());
        if (StringUtils.equals(BizConstant.ROLE_USER_IS_UN_AUTH,roleUserDto.getIsAuth())) {
            queryWrapper.notIn(!userIds.isEmpty(),SysUser::getId, userIds);
        }else {
            if(userIds.isEmpty()){
                return Result.OK(Collections.emptyList());
            }
            queryWrapper.in(SysUser::getId, userIds);
        }
        Page<SysUser> page = new Page<>(roleUserDto.getPageNo(), roleUserDto.getPageSize());
        IPage<SysUser> pageList = this.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    @Override
    public Result<?> addSysUserRole(SysUserRoleDto sysUserRoleDto) {
        try {
            SysRole sysRole = sysRoleService.getById(sysUserRoleDto.getRoleId());
            if(sysRole == null){
                return Result.error("未找到角色，请刷新重试！");
            }
            for (String sysUserId : sysUserRoleDto.getUserIdList()) {
                SysUserRole one = sysUserRoleService.lambdaQuery().eq(SysUserRole::getRoleId, sysRole.getId()).eq(SysUserRole::getUserId, sysUserId).one();
                if (one == null) {
                    sysUserRoleService.save(new SysUserRole(sysUserId, sysRole.getId()));
                }
            }
            return Result.ok("操作成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<?> deleteRoleUser(SysUserRoleDto sysUserRoleDto) {
        try {
            if(StringUtils.isEmpty(sysUserRoleDto.getRoleId())){
                return Result.error("参数不完整！");
            }
            for (String sysUserId : sysUserRoleDto.getUserIdList()) {
                SysUserRole one = sysUserRoleService.lambdaQuery()
                        .eq(SysUserRole::getRoleId, sysUserRoleDto.getRoleId())
                        .eq(SysUserRole::getUserId, sysUserId).one();
                if (one != null) {
                    sysUserRoleService.removeById(one.getId());
                }

            }
            return Result.ok("删除成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    @Override
    public Result<?> restPassword(String userId) {
        SysUser user = this.getById(userId);
        if(user == null){
            return Result.error("用户不存在，请刷新重试！");
        }
        user.setPassword(BizConstant.USER_DEFAULT_PASSWORD);
        processPassword(user);
        if(this.updateById(user)){
            return Result.ok("重置成功!新密码为【"+BizConstant.USER_DEFAULT_PASSWORD+"】。");
        }else{
            return Result.error("重置失败！");
        }
    }

    @Override
    public Result<?> checkUserIsEffective(SysUser sysUser) {
        Result<?> result = new Result<Object>();
        if (sysUser == null) {
            result.error500("该用户不存在，请注册");
//            baseCommonService.addLog("用户登录失败，用户不存在！", CommonConstant.LOG_TYPE_1, null);
            return result;
        }
        if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
//            baseCommonService.addLog("用户登录失败，用户名:" + sysUser.getUsername() + "已注销！", CommonConstant.LOG_TYPE_1, null);
            result.error500("该用户已注销");
            return result;
        }
        //情况3：根据用户信息查询，该用户已冻结
        if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) {
//            baseCommonService.addLog("用户登录失败，用户名:" + sysUser.getUsername() + "已冻结！", CommonConstant.LOG_TYPE_1, null);
            result.error500("该用户已冻结");
            return result;
        }
        return result;
    }

    private void processPassword(SysUser sysUser) {
        String salt = oConvertUtils.randomGen(8);
        sysUser.setSalt(salt);
        String passwordEncode = PasswordUtil.encrypt(
                sysUser.getUsername(),
                sysUser.getPassword(),
                salt
        );
        sysUser.setPassword(passwordEncode);
    }
}
